package com.hboxs.asl.controller.asl.member;

import com.hboxs.asl.*;
import com.hboxs.asl.controller.asl.BaseController;
import com.hboxs.asl.entity.*;
import com.hboxs.asl.service.*;
import com.hboxs.asl.util.SettingUtils;
import com.hboxs.asl.util.SpringUtils;
import com.hboxs.asl.util.WebUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.*;

/**
 * Controller - 用户
 */
@Controller("aslMemberController")
@RequestMapping("/weChat/member")
public class MemberControl extends BaseController {

    @Resource(name = "memberServiceImpl")
    private MemberService memberService;
    @Resource(name = "feedbackServiceImpl")
    private FeedbackService feedbackService;
    @Resource(name = "enterpriseServiceServiceImpl")
    private EnterpriseServiceService enterpriseServiceService;
    @Resource(name = "giveawayServiceImpl")
    private GiveawayService giveawayService;
    @Resource(name = "orderServiceImpl")
    private OrderService orderService;
    @Resource(name = "pointTradeServiceImpl")
    private PointTradeService pointTradeService;
    @Resource(name = "cartServiceImpl")
    private CartService cartService;
    @Resource(name = "fileServiceImpl")
    private FileService fileService;

    protected Logger logger = Logger.getLogger(getClass().getName());

    /**
     * 自动登录member
     *
     * @param username
     * @param request
     * @param response
     * @param session
     * @return
     */
    @RequestMapping(value = "/autoLogin", method = RequestMethod.GET)
    public String autoLogin(String redirect_url, String username, HttpServletRequest request, HttpServletResponse response, HttpSession session) {

        if (StringUtils.isEmpty(username)) {
            logger.error(SpringUtils.getMessage("shop.common.invalid"));
            return "/yijing/404";
        }
        Member member;
        Setting setting = SettingUtils.get();
        member = memberService.findByUsername(username);
        if (member == null) {
            logger.error(SpringUtils.getMessage("shop.login.unknownAccount"));
            return "/yijing/404";
        }
        if (!member.getIsEnabled()) {
            logger.error(SpringUtils.getMessage("shop.login.disabledAccount"));
            return "/yijing/404";
        }
        if (member.getIsLocked()) {
            if (ArrayUtils.contains(setting.getAccountLockTypes(), Setting.AccountLockType.member)) {
                int loginFailureLockTime = setting.getAccountLockTime();
                if (loginFailureLockTime == 0) {
                    logger.error(SpringUtils.getMessage("shop.login.lockedAccount"));
                    return "/yijing/404";
                }
                Date lockedDate = member.getLockedDate();
                Date unlockDate = DateUtils.addMinutes(lockedDate, loginFailureLockTime);
                if (new Date().after(unlockDate)) {
                    member.setLoginFailureCount(0);
                    member.setIsLocked(false);
                    member.setLockedDate(null);
                    memberService.update(member);
                } else {
                    logger.error(SpringUtils.getMessage("shop.login.lockedAccount"));
                    return "/yijing/404";
                }
            } else {
                member.setLoginFailureCount(0);
                member.setIsLocked(false);
                member.setLockedDate(null);
                memberService.update(member);
            }
        }

        member.setLoginIp(request.getRemoteAddr());
        member.setLoginDate(new Date());
        member.setLoginFailureCount(0);
        member.setAmount(new BigDecimal(0));
        memberService.update(member);

        Map<String, Object> attributes = new HashMap<>();
        Enumeration<?> keys = session.getAttributeNames();
        while (keys.hasMoreElements()) {
            String key = (String) keys.nextElement();
            attributes.put(key, session.getAttribute(key));
        }
        session.invalidate();
        session = request.getSession();
        for (Map.Entry<String, Object> entry : attributes.entrySet()) {
            session.setAttribute(entry.getKey(), entry.getValue());
        }
        session.setAttribute(Member.PRINCIPAL_ATTRIBUTE_NAME, new Principal(member.getId(), username));

        WebUtils.addCookie(request, response, Member.USERNAME_COOKIE_NAME, member.getUsername());

        if (redirect_url == null) {
            redirect_url = "";
        }
        return "redirect:" + redirect_url;
    }


    /**
     * 用户登录(若需要做未登录的购物车,request需要传id和key)
     *
     * @param username 手机
     * @param password 密码
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public
    @ResponseBody
    Object submit(String username, String password, HttpServletRequest request, HttpServletResponse response, HttpSession session) {
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            return JsonMessage.error("用户名或密码不能为空");
        }

        Setting setting = SettingUtils.get();
        Member member = memberService.findByUsername(username);

        if (member == null) {
            logger.error(SpringUtils.getMessage("shop.login.unknownAccount"));
            return JsonMessage.error("此账号不存在");
        }
        if (!member.getIsEnabled()) {
            logger.error(SpringUtils.getMessage("shop.login.disabledAccount"));
            return JsonMessage.error("此账号已被禁用");
        }
        if (member.getIsLocked()) {
            if (ArrayUtils.contains(setting.getAccountLockTypes(), Setting.AccountLockType.member)) {
                int loginFailureLockTime = setting.getAccountLockTime();
                if (loginFailureLockTime == 0) {
                    logger.error(SpringUtils.getMessage("shop.login.lockedAccount"));
                    return JsonMessage.error("此账号已被锁定");
                }
                Date lockedDate = member.getLockedDate();
                Date unlockDate = DateUtils.addMinutes(lockedDate, loginFailureLockTime);
                if (new Date().after(unlockDate)) {
                    member.setLoginFailureCount(0);
                    member.setIsLocked(false);
                    member.setLockedDate(null);
                    memberService.update(member);
                } else {
                    logger.error(SpringUtils.getMessage("shop.login.lockedAccount"));
                    return JsonMessage.error("此账号已被锁定");
                }
            } else {
                member.setLoginFailureCount(0);
                member.setIsLocked(false);
                member.setLockedDate(null);

                memberService.update(member);
            }
        }

        if (!password.equals(member.getPassword())) {
            int loginFailureCount = member.getLoginFailureCount() + 1;
            if (loginFailureCount >= setting.getAccountLockCount()) {
                member.setIsLocked(true);
                member.setLockedDate(new Date());
            }
            member.setLoginFailureCount(loginFailureCount);
            memberService.update(member);
            if (ArrayUtils.contains(setting.getAccountLockTypes(), Setting.AccountLockType.member)) {
                logger.error(SpringUtils.getMessage("admin.login.emailLockCount", setting.getAccountLockCount()));
//                    return JsonMessage.error(SpringUtils.getMessage("密码错误，若连续{0}次密码错误账号将被锁定", setting.getAccountLockCount()));
                return JsonMessage.error("密码错误，若连续" + setting.getAccountLockCount() + "次密码错误账号将被锁定");
            } else {
                logger.error(SpringUtils.getMessage("shop.login.incorrectCredentials"));
                return JsonMessage.error("用户名或密码错误");
            }
        }
        member.setLoginIp(request.getRemoteAddr());
        member.setLoginDate(new Date());
        member.setLoginFailureCount(0);

        memberService.update(member);

        session.setAttribute(Member.PRINCIPAL_ATTRIBUTE_NAME, new Principal(member.getId(), username));
        WebUtils.addCookie(request, response, Member.USERNAME_COOKIE_NAME, member.getUsername());

        //获取未登录前的购物车的id和key
        Cart cart = cartService.getCurrentByToken();

        if (cart != null) {
            if (cart.getMember() == null) {
                cartService.merge(member, cart);
            }
        }
        memberService.update(member);
        return JsonMessage.success(
                "token", member.getToken()
                , "tokenExpire", member.getTokenExpire()
                , "name", member.getName()
                , "avator", member.getAvator()
        );
    }


    /**
     * 个人资料页面
     *
     * @param modelMap
     * @return
     */
    @RequestMapping(value = "/info", method = RequestMethod.GET)
    public String info(ModelMap modelMap) {
        try {
            Member member = memberService.getCurrent();
            modelMap.addAttribute("member", member);
            return "/yijing/info";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "/yijing/404";
    }

    /**
     * 个人资料页面-头像
     *
     * @param modelMap
     * @return
     */
    @RequestMapping(value = "/info-avator", method = RequestMethod.GET)
    public String infoAvator(ModelMap modelMap) {
        Member member = memberService.getCurrent();
        modelMap.addAttribute("member", member);
        return "/yijing/info-avator";
    }



    /**
     * 保存头像
     *
     * @param avator 头像
     * @return json
     */
    @RequestMapping(value = "/avator", method = RequestMethod.POST)
    public
    String avator(MultipartFile avator) {
        Member member = memberService.getCurrent();
        if (!fileService.isValid(FileInfo.FileType.image, avator)) {
//            return JsonMessage.error("上传图片大小或格式不正确");
            return "redirect:info.htm?remind=avator_error";
        }

        String url = fileService.upload(FileInfo.FileType.image, avator, false, "avator");

        if (url == null) {
//            return JsonMessage.error("图片上传失败！");
            return "redirect:info.htm?remind=avator_error";
        }
        member.setAvator(url);
        memberService.update(member);
        return "redirect:info.htm?remind=avator_success";
    }

    /**
     * 修改个人资料--昵称
     *
     * @param name
     * @return
     */
    @RequestMapping(value = "/info/name", method = RequestMethod.POST)
    public
    @ResponseBody
    JsonMessage updateName(String name) {
        try {
            Member member = memberService.getCurrent();
            member.setName(name);
            memberService.update(member);
            return JsonMessage.success(name);
        } catch (Exception e) {
            logger.info(e.getMessage());
        }
        return JsonMessage.UNKNOWN_ERROR;
    }

    /**
     * 修改个人资料--手机号码
     *
     * @param phone
     * @return
     */
    @RequestMapping(value = "/info/phone", method = RequestMethod.POST)
    public
    @ResponseBody
    JsonMessage updatePhone(String phone) {
        try {
            Member member = memberService.getCurrent();
            member.setPhone(phone);
            memberService.update(member);
            return JsonMessage.success(phone);
        } catch (Exception e) {
            logger.info(e.getMessage());
        }
        return JsonMessage.UNKNOWN_ERROR;
    }

    /**
     * 修改个人资料--生日
     *
     * @param birth
     * @return
     */
    @RequestMapping(value = "/info/birth", method = RequestMethod.POST)
    public
    @ResponseBody
    JsonMessage updateBirth(Date birth) {
        try {
            Member member = memberService.getCurrent();
            member.setBirth(birth);
            memberService.update(member);
            return JsonMessage.success(birth);
        } catch (Exception e) {
            logger.info(e.getMessage());
        }
        return JsonMessage.UNKNOWN_ERROR;
    }


    /**
     * 充值
     *
     * @param modelMap
     * @return
     */
    @RequestMapping(value = "/recharge", method = RequestMethod.GET)
    public String recharge(ModelMap modelMap) {
        modelMap.addAttribute("gas", giveawayService.findValid());
        return "/yijing/recharge";
    }


    /**
     * 我的订单
     *
     * @param cat
     * @return
     */
    @RequestMapping(value = "/orders", method = RequestMethod.GET)
    public String orders(Integer cat) {
        return "";
    }

    /**
     * 我的钱包
     *
     * @return
     */
    @RequestMapping(value = "/wallet", method = RequestMethod.GET)
    public String wallet() {
        return "/yijing/wallet";
    }

    /**
     * 企业服务
     *
     * @param modelMap
     * @return
     */
    @RequestMapping(value = "/entprServ", method = RequestMethod.GET)
    public String entprServ(ModelMap modelMap) {
        Member member = memberService.getCurrent();
        Set<EnterpriseService> enterpriseServices = member.getEnterpriseServices();
        if (enterpriseServices.size() == 0) {
            enterpriseServices.add(new EnterpriseService());
        }
        modelMap.addAttribute("enterpriseServices", enterpriseServices);
        return "/yijing/corporateServices/company-service";
    }

    /**
     * 企业服务
     *
     * @param enterpriseService
     * @return
     */
    @RequestMapping(value = "/entprServ", method = RequestMethod.POST)
    public String entprServ(EnterpriseService enterpriseService) {
        try {
            Member member = memberService.getCurrent();
            enterpriseService.setMember(member);
            if (enterpriseService.getId() == null) {
                enterpriseServiceService.save(enterpriseService);
            } else {
                enterpriseServiceService.update(enterpriseService);
            }
            return "/yijing/corporateServices/service-success";
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return "/yijing/corporateServices/service-failed";
    }


    /**
     * 反馈信息输入页面
     *
     * @return
     */
    @RequestMapping(value = "/feedback", method = RequestMethod.GET)
    public String feedback() {
        return "/yijing/feedback/feedback";
    }

    /**
     * 生成用户反馈信息
     *
     * @param feedback
     * @return
     */
    @RequestMapping(value = "/feedback", method = RequestMethod.POST)
    public String feedback(Feedback feedback) {
        try {
            feedback.setMember(memberService.getCurrent());
            if (Feedback.validate(feedback) != null) {
                return "/yijing/feedback/feedback-failed";
            }
            feedbackService.save(feedback);
            return "/yijing/feedback/feedback-success";
        } catch (Exception e) {
            logger.info(e.getMessage());
        }
        return "/yijing/feedback/feedback-failed";
    }

    /**
     * 我的下级
     *
     * @param modelMap
     * @return
     */
    @RequestMapping(value = "/children", method = RequestMethod.GET)
    public String children(ModelMap modelMap) {
        Member member = memberService.getCurrent();
        // 下级列表
        List<Member> children = member.getChildren();
        BigDecimal totalPoint = new BigDecimal(0);

        for (Member child : children) {
            List<PointTrade> pointTrades = pointTradeService.findPointTrade(child, member);
            // 用户赠送分销的积分数
            BigDecimal childTotalPoint = new BigDecimal(0);
            Integer childTotalCount = 0;
            for (PointTrade pointTrade : pointTrades) {
                childTotalPoint = childTotalPoint.add(pointTrade.getmParentAmount());
                childTotalCount++;
            }
            child.setTempDistributionPoint(childTotalPoint);
            child.setTempDistributionCount(childTotalCount);

            totalPoint = totalPoint.add(childTotalPoint);
        }

        modelMap.addAttribute("member", member);
        modelMap.addAttribute("totalPoint", totalPoint);
        return "/yijing/children";
    }

}
